package com.lgl.scs.information.service;

import com.lgl.scsapi.base.dao.DaoSupport;
import com.lgl.scsapi.system.model.PageData;
import com.lgl.scsapi.system.model.ServiceOrder;
import com.lgl.scsapi.util.utils.Constants;
import com.lgl.scsapi.util.utils.Tools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.PoolException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * 地址service
 */
@Slf4j
@Service("addressService")
public class AddressService {
	@Resource(name = "daoSupport")
	private DaoSupport dao;
    @Resource
    private RedisTemplate redisTemplate;

	/**
	 * 获取省份信息列表
	 * @param pd 省份编码或名称
	 * @return 省份信息List集合
	 */
	public List<PageData> listAllProvinces(PageData pd){
		try {
			//如果redis可用，则从redis中取
            if (Constants.REDIS_IS_USABLE) {
                List<PageData> provinceList = redisTemplate.opsForList().range(Constants.UI_PROVINCE, 0, 100);
				if (provinceList != null && !provinceList.isEmpty()) {
					return provinceList;
				}
			}
		}catch (Exception e){
			if (e instanceof PoolException) {
                Constants.REDIS_IS_USABLE = false;
			}
			log.error(e.toString(),e);
		}
		return (List<PageData>) dao.findForList("AddressMapper.listAllProvinces", pd);
	}
	/**
	 * 获取城市信息列表
	 * @param allCityPd 查询相关参数
	 * @return 城市信息List集合
	 */
	public List<PageData> listAllCities(PageData allCityPd){
		return (List<PageData>) dao.findForList("AddressMapper.listAllCities", allCityPd);
	}

	/**
	 * 通过城市拼音首字母获取城市
	 * @param pd 城市拼音等参数
	 * @return 城市信息List集合
	 */
	public List<PageData> listCitiesByWords(PageData pd){
		return (List<PageData>) dao.findForList("AddressMapper.listCitiesByWords", pd);
	}
	/**
	 * 获取地区，县、市信息列表
	 * @param pd 查询参数
	 * @return 县、市信息list列表
	 */
	public List<PageData> listAllArea(PageData pd){
		String laMapper = "AddressMapper.listAllArea", cityCode = null, areaKey = null;
	    try {
            if (pd != null && !pd.isEmpty()){
                cityCode = pd.getString("cityCode");
                //如果没有城市编码，或redis不可用
                if (!StringUtils.hasText(cityCode) || !Constants.REDIS_IS_USABLE) {
                    return (List<PageData>) dao.findForList(laMapper, pd);
                }
                areaKey = Constants.UI_AREA + cityCode;
                //从redis中取
                long listSize = redisTemplate.opsForList().size(areaKey);
                if (listSize > 0) {
                    return redisTemplate.opsForList().range(areaKey, 0, -1);
                }
            }
        }catch (Exception e){
	        if (e instanceof PoolException){
                Constants.REDIS_IS_USABLE = false;
            }
	        log.error(e.toString(),e);
        }
	    //为防止pd中含有其它参数导致areaKey键存储的值有问题，只保留pd中的城市编码参数
        pd.clear();
	    pd.put("cityCode",cityCode);
        //缓存中不存在，则从数据库中取
        List<PageData> areaList = (List<PageData>) dao.findForList(laMapper, pd);
        if (Constants.REDIS_IS_USABLE) {
            //插入前先删除对应的数据，防止数据重复
        	redisTemplate.delete(areaKey);
        	//(Collection) areaList 这样写，redisTemplate才会把areaList当成list，否则会当成普通对象处理
			//如果不将areaList转为Collection，那存进去的list数据是这样的：[[{a:b}]]，即：list集合中还有list集合
        	redisTemplate.opsForList().rightPushAll(areaKey, areaList);
        }
		return areaList;
	}
	/**
	 * 通过城市名获取城市ID
	 * @param cityName   城市名
	 * @return 城市ID
	 */
	public String findCityIdByName(String cityName){
		return (String) dao.findForObject("AddressMapper.findCityIdByName", cityName);
	}
	/**
	 * 通过区域编码获取城市编码
	 * @param areaCode 区域编码
	 * @return 城市编码
	 */
	public String findCityCodeByAreaCode(String areaCode){
		return (String) dao.findForObject("AddressMapper.findCityCodeByAreaCode", areaCode);
	}
	/**
	 * 通过区/县名称或城市编码获取区/县编码
	 * @param serviceOrder 订单对象
	 * @return 区/县编码
	 */
	public String getAreaCodeByName(ServiceOrder serviceOrder){
		String cityCode = serviceOrder.getSoCityCode(), areaCode = serviceOrder.getSoAreaCode(),
				areaName = serviceOrder.getAreaName();
		String areaKey = Constants.UI_AREA + cityCode;
		if (!StringUtils.hasText(areaName)){
			return areaCode;
		}
		PageData paramPd = new PageData(2);
		//从redis中取出该城市下的所有区域
		List<PageData> areaList = null;
		if (StringUtils.hasText(cityCode)){
			long listSize = redisTemplate.opsForList().size(areaKey);
			if (listSize > 0) {
				areaList = redisTemplate.opsForList().range(areaKey, 0, -1);
			}else {
				paramPd.put("cityCode", cityCode);
				areaList = listAllArea(paramPd);
				//如果是热门城市，则添加到redis中
				if (areaList != null && !areaList.isEmpty() && Tools.isHotCity(cityCode)){
					//插入前先删除对应的数据，防止数据重复
					redisTemplate.delete(areaKey);
					//(Collection) areaList 这样写，redisTemplate才会把areaList当成list，否则会当成普通对象处理
					//如果不将areaList转为Collection，那存进去的list数据是这样的：[[{a:b}]]，即：list集合中还有list集合
					redisTemplate.opsForList().rightPushAll(areaKey, areaList);
				}
			}
		}
		if (areaList == null || areaList.isEmpty()){
			paramPd.put("areaName", areaName);
			areaList = listAllArea(paramPd);
		}
		for (PageData areaPd : areaList) {
			if (areaName.equals(areaPd.getString("areaName"))) {
				return areaPd.getString("areaCode");
			}
		}
		return areaCode;
	}
}
